import backtrader as bt

class MaCrossStrategy(bt.Strategy):
    """
    一个简单的双均线交叉策略。
    当短期均线上穿长期均线时（金叉），买入。
    当短期均线下穿长期均线时（死叉），卖出。
    """
    params = (
        ('fast_len', 20),
        ('slow_len', 50),
        ('printlog', True), # 是否打印交易日志
    )

    def __init__(self):
        self.dataclose = self.datas[0].close
        self.order = None
        self.buyprice = None
        self.buycomm = None

        # 计算移动平均线
        self.fast_ma = bt.indicators.SimpleMovingAverage(
            self.datas[0], period=self.p.fast_len
        )
        self.slow_ma = bt.indicators.SimpleMovingAverage(
            self.datas[0], period=self.p.slow_len
        )

        # 使用CrossOver指标来检测金叉和死叉
        self.crossover = bt.indicators.CrossOver(self.fast_ma, self.slow_ma)

    def log(self, txt, dt=None, doprint=False):
        """ 日志记录函数 """
        if self.params.printlog or doprint:
            dt = dt or self.datas[0].datetime.date(0)
            print(f'{dt.isoformat()}, {txt}')

    def notify_order(self, order):
        """ 订单状态通知 """
        if order.status in [order.Submitted, order.Accepted]:
            # 订单已提交/接收，无需处理
            return

        if order.status in [order.Completed]:
            if order.isbuy():
                self.log(
                    f'BUY EXECUTED, Price: {order.executed.price:.2f}, Cost: {order.executed.value:.2f}, Comm {order.executed.comm:.2f}'
                )
                self.buyprice = order.executed.price
                self.buycomm = order.executed.comm
            else:  # Sell
                self.log(f'SELL EXECUTED, Price: {order.executed.price:.2f}, Cost: {order.executed.value:.2f}, Comm {order.executed.comm:.2f}')

            self.bar_executed = len(self)

        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            self.log('Order Canceled/Margin/Rejected')

        self.order = None

    def notify_trade(self, trade):
        """ 交易结果通知 """
        if not trade.isclosed:
            return
        self.log(f'OPERATION PROFIT, GROSS {trade.pnl:.2f}, NET {trade.pnlcomm:.2f}')


    def next(self):
        """ 策略主逻辑 """
        # 检查是否有订单正在处理
        if self.order:
            return

        # 检查是否持有仓位
        if not self.position:
            # 如果没有仓位，并且出现金叉
            if self.crossover > 0:
                self.log(f'BUY CREATE, Close: {self.dataclose[0]:.2f}')
                # 创建买入订单
                self.order = self.buy()
        else:
            # 如果持有仓位，并且出现死叉
            if self.crossover < 0:
                self.log(f'SELL CREATE, Close: {self.dataclose[0]:.2f}')
                # 创建卖出订单
                self.order = self.sell() 